-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Lint][AMDGPU] No store to const addrspace #109181
Conversation
@llvm/pr-subscribers-llvm-support @llvm/pr-subscribers-backend-amdgpu Author: None (jofrn) ChangesFull diff: https://github.com/llvm/llvm-project/pull/109181.diff 2 Files Affected:
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 06a67346fbf959..805c9ef7b72729 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4224,6 +4224,19 @@ void Verifier::visitLoadInst(LoadInst &LI) {
visitInstruction(LI);
}
+static bool isConstantAddressSpace(unsigned AS) {
+ switch (AS) {
+ using namespace AMDGPUAS;
+ case CONSTANT_ADDRESS: case CONSTANT_ADDRESS_32BIT:
+ case CONSTANT_BUFFER_0: case CONSTANT_BUFFER_1: case CONSTANT_BUFFER_2: case CONSTANT_BUFFER_3:
+ case CONSTANT_BUFFER_4: case CONSTANT_BUFFER_5: case CONSTANT_BUFFER_6: case CONSTANT_BUFFER_7:
+ case CONSTANT_BUFFER_8: case CONSTANT_BUFFER_9: case CONSTANT_BUFFER_10: case CONSTANT_BUFFER_11:
+ case CONSTANT_BUFFER_12: case CONSTANT_BUFFER_13: case CONSTANT_BUFFER_14: case CONSTANT_BUFFER_15:
+ return true;
+ default: return false;
+ }
+}
+
void Verifier::visitStoreInst(StoreInst &SI) {
PointerType *PTy = dyn_cast<PointerType>(SI.getOperand(1)->getType());
Check(PTy, "Store operand must be a pointer.", &SI);
@@ -4246,6 +4259,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
Check(SI.getSyncScopeID() == SyncScope::System,
"Non-atomic store cannot have SynchronizationScope specified", &SI);
}
+ if (TT.isAMDGPU()) {
+ Check(!isConstantAddressSpace(SI.getPointerAddressSpace()),
+ "Store cannot be to constant addrspace", &SI);
+ }
visitInstruction(SI);
}
diff --git a/llvm/test/CodeGen/AMDGPU/const-store.ll b/llvm/test/CodeGen/AMDGPU/const-store.ll
new file mode 100644
index 00000000000000..9447ef9db59986
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/const-store.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple=amdgcn < %s |& FileCheck %s
+
+define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {
+; CHECK: Store cannot be to constant addrspace
+; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out
+ %r = add i32 %a, %b
+ store i32 %r, ptr addrspace(4) %out
+ ret void
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
7a77ede
to
5469cf1
Compare
Ensure store to const addrspace is not allowed by IR Verifier.
5469cf1
to
a099028
Compare
llvm/lib/IR/Verifier.cpp
Outdated
@@ -4224,6 +4224,33 @@ void Verifier::visitLoadInst(LoadInst &LI) { | |||
visitInstruction(LI); | |||
} | |||
|
|||
static bool isConstantAddressSpace(unsigned AS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constant address space is not an AMD only thing. I'm thinking probably we can split this function into target dependent (for example, to query whether an AS is a constant AS) and independent part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would the independent part contain if we do not have a use case for it yet?
Was there any discussion about this? I'm not sure if it should be a verifier error or just undefined behaviour at run time. Also there are other instructions that write to memory, like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must be UB, and not a verifier error. For example, we allow constant->flat casts. We do not want to have to consider the address spaces involved when folding something like store (addrspacecast ptr addrspace(4) %val to ptr)
Plus long term I don't think we should have a constant address space at all. |
It can be guarded with a flag perhaps. There was discussion to catch this in some way or another since it leads to more confusing error messages later on. Alternatively, we can have these checks go in a separate pass. |
The addrspace in |
These kinds of checks should go into the Lint pass instead of the Verifier pass. |
You're reading the example too literally. It should be valid for a pass to strip away the cast, and store directly to the original address space of the pointer without considering any special information. It would be a target specific burden placed on any IR transformation, which is not OK. This type of check belongs in Lint, which hardly ever gets used and I'm not sure is worth the effort |
a82bcdc
to
b3fea0b
Compare
%r = add i32 %a, %b | ||
store i32 %r, ptr addrspace(4) %out | ||
ret void | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test atomicrmw, cmpxchg, and a memset, memcpy? Also at least the addrspace(6) case
@@ -0,0 +1,9 @@ | |||
; RUN: not opt -mtriple=amdgcn --passes=lint --lint-abort-on-error %s -o - |& FileCheck %s | |||
|
|||
define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) addrspace(4) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no reason to set the address space of the function
@@ -0,0 +1,9 @@ | |||
; RUN: not opt -mtriple=amdgcn --passes=lint --lint-abort-on-error %s -o - |& FileCheck %s | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
negative test with a different target
@@ -0,0 +1,9 @@ | |||
; RUN: not opt -mtriple=amdgcn --passes=lint --lint-abort-on-error %s -o - |& FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should move this to test/Analysis/Lint
0b69206
to
b1c3d38
Compare
b1c3d38
to
4553484
Compare
14a876d
to
2c640e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New approach looks reasonable to me.
llvm/lib/Analysis/Lint.cpp
Outdated
if (TT.isAMDGPU()) { | ||
switch(AS) { | ||
using namespace AMDGPUAS; | ||
case CONSTANT_ADDRESS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a helper in AMDGPUAddrSpace.h? I'd expect this logic to already exist somewhere, but it looks like AMDGPUAA is only looking for CONSTANT_ADDRESS and nothing else:
if (LI->getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) |
2c640e5
to
393311c
Compare
llvm/lib/Analysis/Lint.cpp
Outdated
@@ -401,6 +403,10 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc, | |||
"Unusual: Address one pointer dereference", &I); | |||
|
|||
if (Flags & MemRef::Write) { | |||
if (TT.isAMDGPU()) | |||
Check(!AMDGPU::isConstantAddressSpace(UnderlyingObject->getType()->getPointerAddressSpace()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible or better to do the check via TTI? I'm not sure if it's a good idea to do the check based on triple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of verification doesn't really fit in with TTI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear, the "check" I meant here was AMDGPU::isConstantAddressSpace
.
a3a013d
to
ed164f3
Compare
llvm/lib/Analysis/Lint.cpp
Outdated
@@ -401,6 +403,10 @@ void Lint::visitMemoryReference(Instruction &I, const MemoryLocation &Loc, | |||
"Unusual: Address one pointer dereference", &I); | |||
|
|||
if (Flags & MemRef::Write) { | |||
if (TT.isAMDGPU()) | |||
Check(!AMDGPU::isConstantAddressSpace(UnderlyingObject->getType()->getPointerAddressSpace()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of verification doesn't really fit in with TTI
define amdgpu_kernel void @memcpy_to_const(ptr addrspace(6) %dst, ptr %src) { | ||
; CHECK0: Undefined behavior: Write to memory in const addrspace | ||
; CHECK0-NEXT: call void @llvm.memcpy.p6.p0.i32(ptr addrspace(6) %dst, ptr %src, i32 256, i1 false) | ||
call void @llvm.memcpy.px.py.i32(ptr addrspace(6) %dst, ptr %src, i32 256, i1 false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the actual address spaces, not x y
8fa566a
to
251171b
Compare
switch (AS) { | ||
using namespace AMDGPUAS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch (AS) { | |
using namespace AMDGPUAS; | |
using namespace AMDGPUAS; | |
switch (AS) { |
251171b
to
56fa4e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with nit
; CHECK0-NEXT: %void = atomicrmw add ptr addrspace(4) %dst, i32 %src acquire | ||
%void = atomicrmw add ptr addrspace(4) %dst, i32 %src acquire | ||
ret void | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe test arbitrary call that may write (those probably should not fail )
56fa4e8
to
5f9f282
Compare
5f9f282
to
ae211fa
Compare
Ensure store to const addrspace is not allowed by Linter.
Ensure store to const addrspace is not allowed by Linter.
Ensure store to const addrspace is not allowed by Linter.
Ensure store to const addrspace is not allowed by Linter.